<?php

namespace App\Exceptions;

use App\Models\ApiResult;
use App\Services\Base\CacheService;
use App\Services\Base\MsgService;
use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Log;
use Illuminate\Validation\UnauthorizedException;
use Symfony\Component\HttpKernel\Exception\MethodNotAllowedHttpException;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Throwable;

class Handler extends ExceptionHandler
{
    /**
     * A list of the exception types that are not reported.
     *
     * @var array
     */
    protected $dontReport = [
        //
    ];

    /**
     * A list of the inputs that are never flashed for validation exceptions.
     *
     * @var array
     */
    protected $dontFlash = [
        'current_password',
        'password',
        'password_confirmation',
    ];

    /**
     * Register the exception handling callbacks for the application.
     *
     * @return void
     */
    public function register()
    {
        $this->reportable(function (Throwable $e) {
            //

        });
    }

    /* Report or log an exception.
    *
    * @param Exception $e
    * @return void
    * @throws Throwable
    */
    public function report(Throwable $e)
    {
//        if ($this->shouldReport($e)) {
//        }
//        parent::report($e);
    }

    /**
     * Render an exception into an HTTP response.
     *
     * @param \Illuminate\Http\Request $request
     * @param \Throwable $e
     * @return \Symfony\Component\HttpFoundation\Response
     *
     * @throws \Throwable
     */
    public function render($request, \Throwable $e)
    {
        if (strpos($request->getRequestUri(), "/admin") === 0) { //判断后台
            return parent::render($request, $e);
        }

        if ($e instanceof UnauthorizedException) {
            return response()->json(ApiResult::failure($e->getCode(), trans("cs.auth_failed")));
        }

        if ($e instanceof NotFoundHttpException) {
            return response()->json(ApiResult::failure($e->getCode(), trans("cs.interface_not_exist")));
        }

        if ($e instanceof MethodNotAllowedHttpException) {
            return response()->json(ApiResult::failure($e->getCode(), trans("cs.method_not_exist")));
        }


//        if ($e instanceof ApiException) {
//            return response()->json(ApiResult::failure($e->getCode(), trans($e->getMessage())));
//        }

        if ($e instanceof \Exception || $e instanceof \Throwable) {
            $code = $e->getCode();
            if (!(is_numeric($code) && $code > M_START && $code <= M_END)) {
                $code = 405;
            }
            $this->logInfo($e, $request, $code);
            if ($code == SHOW_MESSAGE) {
                return response()->json(ApiResult::failure($code, $e->getMessage()));
            }

            $msg = $this->checkMessage($request, $e->getMessage(), $code);
            return response()->json(ApiResult::failure($code, $msg));
        }

        return response()->json(ApiResult::failure(0, __('系统异常', [], app()->getLocale())));


    }

    private function logInfo($e, Request $req, $code)
    {
        $token = $req->bearerToken();
        $user_id_name = '';
        if ($token) {
            $user = CacheService::hGet(R_LOGIN_TOKEN_INFO, $token);
            if ($user && $user != R_REDIS_ERROR) {
                $user = json_decode($user, true);
                $user_id_name = $user['uid'] . '_' . $user['username'];
            }
        }

        $s = sprintf("[%s][%s]%s:%d  %s (%d) [%s]", $req->getRequestUri(), $user_id_name, $e->getFile(), $e->getLine(), $e->getMessage(), $e->getCode(), get_class($e));
        if ($code != LOG_NO_QUERY_STRING) {
            Log::error($s, $req->all());
        } else {
            Log::error($s);
        }
    }

    private function checkMessage($request, $msg, $code)
    {
        $to_msg = MsgService::toMessage($code);
        if (!$to_msg) {
            $to_msg = __('系统异常', [], app()->getLocale());
        }
        return $to_msg;
    }
}
